﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PPTHelper
{
    class PrintScreen
    {


        /// <summary>
        /// 取鼠标屏幕相对位置
        /// </summary>
        /// <param name="screen">屏幕</param>
        /// <returns></returns>
        public static Point GetMousePosition(Screen screen)
        {
            var pt = Control.MousePosition;
            var rect = screen.Bounds;
            if (!rect.Contains(pt)) return new Point(-1, -1);
            return new Point(Math.Abs(rect.X) + pt.X, Math.Abs(rect.Y) + pt.Y);
        }

        /// <summary>
        /// 取鼠标绝对位置
        /// </summary>
        /// <param name="i">屏幕号</param>
        /// <param name="x">相对X</param>
        /// <param name="y">相对Y</param>
        /// <param name="w">相对矩形宽度</param>
        /// <param name="h">相对矩形高度</param>
        /// <returns></returns>
        public static Point GetMouseAbsolute(int i, int x, int y, int w, int h)
        {
            var pt = new Point(0, 0);
            var screens = Screen.AllScreens;
            if (i < 0 || i >= screens.Length) return pt;
            var rect = screens[i].Bounds;
            pt = new Point((int)(rect.Width / 1.0 / w * x + rect.X), (int)(rect.Height / 1.0 / h * y + rect.Y));
            return pt;
        }

        //输出图片缩小倍数
        public static int Zoom { get; set; } = 2;

        public static byte[] GetScreenImage(int i)
        {
            var screens = Screen.AllScreens;
            if (i < 0 || i >= screens.Length) i = 0;
            var bytes = GetScreenImage(screens[i]);
            return bytes;
        }

        /// <summary>
        /// 屏幕截图
        /// </summary>
        /// <param name="screen"></param>
        /// <returns>JPG字节数组</returns>
        static byte[] GetScreenImage(Screen screen)
        {
            var result = Properties.Resources.PPT_jpg;
            try
            {
                var image = CopyScreen(screen);
                var w = image.Width / Zoom;
                var h = image.Height / Zoom;
                image = image.GetThumbnailImage(w, h, null, IntPtr.Zero);
                using (var ms = new MemoryStream())
                {
                    image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                    result = ms.ToArray();
                }
            }
            catch (Exception ex)
            {
                Log.Info("GetScreen：" + ex.Message);
            }
            finally
            {
                GC.Collect();
            }
            Log.Info($"ScreenImageLength：{result.Length}");
            return result;
        }

        /// <summary>
        /// 屏幕截图
        /// </summary>
        /// <param name="screen">屏幕</param>
        /// <param name="cursors">是否包含光标</param>
        /// <returns>Image</returns>
        static Image CopyScreen(Screen screen, bool cursors = true)
        {
            Rectangle rect = screen.Bounds;
            int iWidth = rect.Width;
            int iHeight = rect.Height;
            Image myImage = new Bitmap(iWidth, iHeight);

            using (var g = Graphics.FromImage(myImage))
            {
                g.CopyFromScreen(rect.Location, new Point(0, 0), new Size(iWidth, iHeight));
                if (cursors)
                {
                    var cur = GetCursor();
                    var pt = GetMousePosition(screen);
                    if (cur.flags == CURSOR_SHOWING && pt.X > -1 && pt.Y > -1)
                    {
                        var cursor = new Cursor(cur.hCursor);
                        var curRect = new Rectangle(pt.X, pt.Y, cursor.Size.Width * Zoom, cursor.Size.Height * Zoom); //放大
                        cursor.DrawStretched(g, curRect);
                    }
                }
            }
            return myImage;
        }


        [StructLayout(LayoutKind.Sequential)]
        struct CURSORINFO
        {
            public Int32 cbSize;        // Specifies the size, in bytes, of the structure.
            public Int32 flags;         // Specifies the cursor state.								
            public IntPtr hCursor;          // Handle to the cursor.
            public Point ptScreenPos;       // A POINT structure that receives the screen coordinates of the cursor.
        }

        [DllImport("user32.dll")]
        static extern bool GetCursorInfo(out CURSORINFO pci);
        const Int32 CURSOR_SHOWING = 0x00000001;

        static CURSORINFO GetCursor()
        {
            CURSORINFO pci;
            pci.cbSize = Marshal.SizeOf(typeof(CURSORINFO));
            GetCursorInfo(out pci);
            return pci;
        }


    }



}
